﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using LyncServerExtension.PluginModel;

namespace LyncServerExtension
{
    /// <summary>
    /// Class to represent a provider for plugin result builders.
    /// </summary>
    public sealed class LyncResultBuilderPluginProvider : ILyncResultBuilderProvider, IPluginContext, IDisposable
    {
        private string pluginDirectoryPath;
        private Dictionary<string, ILyncResultBuilderPlugin> resultBuilderPlugins = new Dictionary<string, ILyncResultBuilderPlugin>();
        private AssemblyResolver pluginResourcesResolver;

        /// <summary>
        /// Initializes a new instance of the <see cref="LyncResultBuilderPluginProvider"/> class.
        /// </summary>
        /// <param name="pluginDirectoryPath">The plugin directory path.</param>
        public LyncResultBuilderPluginProvider(string pluginDirectoryPath)
        {
            if (pluginDirectoryPath == null)
                throw new ArgumentNullException("pluginDirectoryPath");

            this.pluginDirectoryPath = pluginDirectoryPath;
        }

        public void Dispose()
        {
            UnloadPlugins();
        }

        /// <summary>
        /// Loads the plugins.
        /// </summary>
        public void LoadPlugins()
        {
            pluginResourcesResolver = new AssemblyResolver();
            pluginResourcesResolver.Paths.Add(pluginDirectoryPath);

            IPlugin[] plugins = PluginManager.Instance.GetPluginLastVersions(pluginDirectoryPath);

            foreach (var plugin in plugins)
            {
                ILyncResultBuilderPlugin resultBuilderPlugin = plugin as ILyncResultBuilderPlugin;
                if (resultBuilderPlugin != null)
                {
                    resultBuilderPlugins.Add(resultBuilderPlugin.Id, resultBuilderPlugin);
                    resultBuilderPlugin.OnLoad(this);
                }
            }
        }

        /// <summary>
        /// Unloads the plugins.
        /// </summary>
        public void UnloadPlugins()
        {
            foreach (var resultBuilderPlugin in resultBuilderPlugins.Values)
                resultBuilderPlugin.OnUnload();

            resultBuilderPlugins.Clear();

            pluginResourcesResolver.Dispose();
        }

        /// <summary>
        /// Gets a result builder matching the given id, and initialized with the given culture.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="culture">The culture.</param>
        /// <returns>
        /// The result builder.
        /// </returns>
        public ILyncResultBuilder GetResultBuilder(string id, string culture)
        {
            ILyncResultBuilderPlugin resultBuilder;

            if (resultBuilderPlugins.TryGetValue(id, out resultBuilder))
            {
                try
                {
                    resultBuilder.Culture = new CultureInfo(culture);
                }
                catch (Exception)
                {
                    resultBuilder.Culture = CultureInfo.CurrentCulture;
                }
            }
            return resultBuilder;
        }
    }
}
